﻿using System;
using YmtAuth.Common.Extend;
using YmtSystem.CrossCutting;

namespace YmtAuth.Domain.Model.Safe
{
    /// <summary>
    /// IP 区域验证
    /// </summary>
    public class IpAreaInfoAuthEntity
    {
        public class IpAreaInfo
        {
            public long Start { get; private set; }          
            public string Country { get; private set; }
            public string Province { get; private set; }           
            public string City { get; private set; }          

            protected IpAreaInfo()
            {

            }
            public string GetArea()
            {
                return string.Format("{0}|{1}|{2}", this.Country, this.Province, this.City);
            }
        }

        public string GetArea()
        {
            return string.Format("{0}|{1}|{2}", this.Country, this.Province, this.City);
        }

        public int UserId { get; private set; }
        public string Country { get; private set; }
        public string Province { get; private set; }
        public string City { get; private set; }
        public int AuthStatus { get; private set; }
        public DateTime? AuthTime { get; private set; }      
        public DateTime CreateTime { get; private set; }
        public string AppSource { get; private set; }
        public DateTime? LastLoginTime { get; private set; }
        public DateTime? LastUpdateTime { get; private set; }
        public string Ip { get; private set; }

        /// <summary>
        /// IP区域数据的收集来源；有以下几类：TokenAuth(token认证/获取用户token), Login(登录), Register(注册), AuthIpArea(IP区域认证), AuthDevice(设备认证)
        /// </summary>
        public string IPAreaSource { get; private set; }
        

        public IpAreaInfoAuthEntity(int userid, string country, string province, string city,string ip
            , string appSource = "auth", int authStatus = 0, string ipAreaSource = null)
        {
            this.UserId = userid;
            this.Country = country;
            this.Province = province;
            this.City = city;         
            this.AppSource = appSource;
            this.CreateTime=DateTime.Now;
            this.LastUpdateTime=DateTime.Now;
            this.LastLoginTime=DateTime.Now;
            this.AuthStatus = authStatus;
            this.AuthTime=DateTime.Now;
            this.Ip = ip;
            this.IPAreaSource = ipAreaSource;
        }

        public static long IpConvertToLong(string ip)
        {
            YmtSystemAssert.AssertArgumentNotNull(ip, "ip 不能为空");
            YmtSystemAssert.AssertArgumentNotEmpty(ip, "ip 不能为空");

            var ipArray = CleanIP(ip).Split(new char[] { '.' });
            YmtSystemAssert.AssertArgumentTrue(ipArray.Length==4,"Ip段位错误");
            var result = Math.Pow(2, 24)*Convert.ToInt32(ipArray[0])
                + Math.Pow(2, 16) * Convert.ToInt32(ipArray[1])
                + Math.Pow(2, 8) * Convert.ToInt32(ipArray[2])
                + Math.Pow(2, 0) * Convert.ToInt32(ipArray[3]);
            return Convert.ToInt64(result);
        }
        public static string CleanIP(string ip)
        {
            var tempIPArr = ip.Split(new char[] {','});

            return tempIPArr[0];
        }

        /// <summary>
        /// IP转换（过滤无效IP）
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="ipStart"></param>
        /// <returns></returns>
        public static bool IpConvertToLong(string ip, out long ipStart)
        {
            ipStart = -1L;

            if (string.IsNullOrEmpty(ip))
            {
                return false;
            }

            var ipArray = CleanIP(ip).Split(new char[] { '.' });
            if (ipArray.Length != 4)
                return false;

            var result = Math.Pow(2, 24) * Convert.ToInt32(ipArray[0])
                + Math.Pow(2, 16) * Convert.ToInt32(ipArray[1])
                + Math.Pow(2, 8) * Convert.ToInt32(ipArray[2])
                + Math.Pow(2, 0) * Convert.ToInt32(ipArray[3]);

            ipStart = Convert.ToInt64(result);

            return true;
        }

        public void SetAuthStatus(bool success, string ipAreaSource)
        {
            this.AuthStatus = success ? 200 : -200;
            this.LastUpdateTime=DateTime.Now;
            this.LastLoginTime = DateTime.Now;
            this.AuthTime=DateTime.Now;

            this.IPAreaSource = ipAreaSource;
        }

        /// <summary>
        /// 成功则更新IP区域认证状态为成功
        /// </summary>
        /// <param name="status"></param>
        public void SetAuthStatus(int status)
        {
            this.AuthStatus = status; 
            this.AuthTime = DateTime.Now;                
            
        }

        public void FlushLastUpdateTime()
        {
            this.LastUpdateTime=DateTime.Now;
            this.LastLoginTime = DateTime.Now;
        }

        public void FlushLoginIp(string ip)
        {
            this.Ip = ip;
        }

        public bool AuthIsSuccess()
        {
            return this.AuthStatus == 200;
        }

        public bool NotAuth()
        {
            return this.AuthStatus == 0;
        }

        public bool AuthFail()
        {
            return this.AuthStatus == -200;
        }

        public void FlushSource(string source)
        {
            this.AppSource = source;
        }

        public override bool Equals(object obj)
        {            
            if (!(obj is IpAreaInfoAuthEntity)) return false;
            var o = obj as IpAreaInfoAuthEntity;
            if (o == null) return false;
            if (ReferenceEquals(o, this)) return true;
            return this.UserId==o.UserId &&  this.Country==o.Country &&this.Province == o.Province && this.City == o.City;
        }

        public override int GetHashCode()
        {
            return this.UserId.GetHashCode() ^ this.Country.GetHashCode() ^ this.Province.GetHashCode() ^ this.City.GetHashCode();
        }

        protected IpAreaInfoAuthEntity()
        {

        }
    }   
}
